import { Injectable } from "@angular/core";
import { SecureStorage, SecureStorageObject } from "@ionic-native/secure-storage";
import { Observable, Subject } from 'rxjs';
import { Storage } from '@ionic/storage';
import { TokenServiceInerface } from "http-service";

declare let window: any;

let gSecureStorageService: SecureStorageService = null;

@Injectable()
export class SecureStorageService implements TokenServiceInerface {

  private storageService: SecureStorageObject = null;

  constructor(private secureStorage: SecureStorage, private storage: Storage) {
    if (gSecureStorageService) {
      return gSecureStorageService;
    }
    gSecureStorageService = this;
  }


  ready(): Observable<boolean> {
    if (window.cordova && this.storageService === null) {
      return Observable.fromPromise(this.secureStorage.create('cn_csg_wudang_security_storage'))
        .do((secureStorageObj: SecureStorageObject) => {
          this.storageService = secureStorageObj;
        })
        .map(() => true);
    }
    return Observable.of(true);

    // , (error: any) => {
    //   alert("请设置锁屏密码后重新打开应用");
    // }
  }

  async clearToken() {
    let tokenKey = "access_token";
    if (window.cordova) {
      // tslint:disable-next-line:no-unused-expression
      // this.storageService && this.storageService.remove(tokenKey);
      let keys = await this.storageService.keys();
      if (keys.indexOf(tokenKey) > -1) {
        await this.storageService.remove(tokenKey);
      }
      if (keys.indexOf('popId') > -1) {
        await this.storageService.remove("popId");
      }
    } else {
      // return this.storage.remove(tokenKey);
      let keys = await this.storage.keys();
      if (keys.indexOf(tokenKey) > -1) {
        this.storage.remove(tokenKey);
      }
      if (keys.indexOf('popId') > -1) {
        await this.storage.remove("popId");
      }
    }
  }

  getToken() {
    return this.get("access_token");
  }

  getAuthorizationString() {
    return this.get("access_token")
      .catch((error) => {
        return Observable.of(null);
      })
      .map((val: string) => {
        if (val && val.length > 0) {
          return "Bearer " + val;
        }
        return null;
      });
  }

  get(key): Observable<string> {
    if (window.cordova) {
      return this.ready().flatMap((ready: boolean) => {
        return ready ? Observable.fromPromise(this.storageService.get(key)).catch((err) => Observable.of(null)) : Observable.of(null);
      });
    }
    else {
      return Observable.fromPromise(this.storage.get(key));
    }
  }

  set(key, value) {
    if (window.cordova) {
      this.ready().flatMap((ready: boolean) => {
        if (this.storageService) {
          return Observable.fromPromise(this.storageService.set(key, value));
        }
        return Observable.of(null);
      })
        .subscribe(() => {
          // TODO
        }, (error) => {
          // TODO
        });
    }
    else {
      return Observable.fromPromise(this.storage.set(key, value));
    }

  }

  setToken(key, value) {
    if (window.cordova) {
      if (this.storageService) {
        return Observable.fromPromise(this.storageService.set(key, value));
      }
      return Observable.of(null);
    } else {
      return Observable.fromPromise(this.storage.set(key, value));
    }
  }

  removeToken(key) {
    if (window.cordova && this.storageService) {
      return Observable.fromPromise(this.storageService.remove(key));
    } else {
      return Observable.fromPromise(this.storage.remove(key));
    }
  }

  remove(key) {
    if (window.cordova && this.storageService) {
       this.storageService.remove(key).then(
           (data) => console.log(data),
           (error) => console.log(error)
       );
    } else {
       this.storage.remove(key);
    }
  }


}
